--双倍采集
local Pickable = require "components/pickable"
local oldSpawnProductLoot = Pickable.SpawnProductLoot
function Pickable:SpawnProductLoot(picker, ...)
    local loot = oldSpawnProductLoot(self, picker, ...)
    if picker and picker:HasTag("doro") then
        local pt = self.inst:GetPosition()
        if self.droppicked and self.inst.components.lootdropper ~= nil then
            pt.y = pt.y + (self.dropheight or 0)
            if self.use_lootdropper_for_product then
                self.inst.components.lootdropper:DropLoot(pt)
            else
                local num = self.numtoharvest or 1
                for i = 1, num do
                    self.inst.components.lootdropper:SpawnLootPrefab(self.product, pt)
                end
            end
        end
    end
    return loot
end

local FishingRod = require "components/fishingrod"
local oldReel = FishingRod.Reel
function FishingRod:Reel(...)
    local a, b = oldReel(self, ...)
    local man = self.fisherman
    if man and man:HasTag("doro") and self.caughtfish and self.caughtfish.prefab then
        local new = SpawnPrefab(self.caughtfish.prefab)
        if new then
            if man.components.inventory ~= nil then
                man.components.inventory:GiveItem(new, nil, man:GetPosition())
            else
                local x, y, z = man.Transform:GetWorldPosition()
                new.components.inventoryitem:DoDropPhysics(x, y, z, true)
            end
        end
    end
    return a, b
end

--双倍收锅
local Stewer = require "components/stewer"
local cooking = require("cooking")
local oldHarvest = Stewer.Harvest
function Stewer:Harvest(harvester, ...)
    if harvester and harvester:HasTag("doro") and self.done then
        if self.product ~= nil then
            local recipe = cooking.GetRecipe(self.inst.prefab, self.product)
            if recipe then
                local oldstacksize = recipe.stacksize
                recipe.stacksize = (recipe.stacksize or 1) * 2
                local result, b = oldHarvest(self, harvester, ...)
                recipe.stacksize = oldstacksize
                return result, b
            end
        end
    end
    return oldHarvest(self, harvester, ...)
end

--所有生物对角色无主动仇恨
local Combat = require "components/combat"
local fakeSetTarget = function(self, target, ...)
    if target and target.doro_ignoreretarget then
        return
    end
    if self.Doro_oldSetTarget then
        return self.Doro_oldSetTarget(self, target, ...)
    end
end
local oldTryRetarget = Combat.TryRetarget
function Combat:TryRetarget(...)
    self.Doro_oldSetTarget = self.SetTarget
    self.SetTarget = fakeSetTarget
    oldTryRetarget(self, ...)
    self.SetTarget = self.Doro_oldSetTarget
end

local oldSetTarget = Combat.SetTarget
function Combat:SetTarget(target, ...)
    if target and target.doro_notarget and target.doro_ignoreretarget then
        return
    end
    return oldSetTarget(self, target, ...)
end

local ChildSpawner = require "components/childspawner"
local oldDoSpawnChild = ChildSpawner.DoSpawnChild
function ChildSpawner:DoSpawnChild(target, prefab, radius, ...)
    if target then
        target.doro_notarget = true
        local child, b, c = oldDoSpawnChild(self, target, prefab, radius, ...)
        target.doro_notarget = nil
        return child, b, c
    end
    return oldDoSpawnChild(self, target, prefab, radius, ...)
end

-- 去除护目镜黑边
AddClassPostConstruct("widgets/gogglesover", function(self)
    local oldToggleGoggles = self.ToggleGoggles
    function self:ToggleGoggles(show, ...)
        if self.owner and self.owner.replica.inventory and self.owner.replica.inventory:EquipHasTag("doro_hat") then
            show = false
        end
        return oldToggleGoggles(self, show, ...)
    end
end)
--眼球可以入锅
AddIngredientValues({ "deerclops_eyeball" }, { meat = 2 })
--橘子可以入锅
AddIngredientValues({ "doro_orange" }, { veggie = 1 })
--进行攻击会瞬移到攻击目标身边缴械攻击目标1秒
local LocoMotor = require "components/locomotor"
local oldPushAction = LocoMotor.PushAction
function LocoMotor:PushAction(bufferedaction, run, try_instant, ...)
    if TheWorld.ismastersim then
        if bufferedaction and bufferedaction.action == ACTIONS.ATTACK then
            local hand = bufferedaction.invobject or
                self.inst.components.inventory and self.inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
            if hand and hand:HasTag("doro_weapon_shadow")
                and hand.components.rechargeable:IsCharged() then
                hand.components.rechargeable:Discharge(5)

                local target = bufferedaction.target
                local pt = target:GetPosition()
                local offset = FindWalkableOffset(pt, math.random() * PI2, math.random(3, 4), 12, nil, nil, nil, nil,
                    true)
                if offset ~= nil then
                    pt.x = pt.x + offset.x
                    pt.z = pt.z + offset.z
                end
                if TheWorld.Map:IsAboveGroundAtPoint(pt.x, pt.y, pt.z) or TheWorld.Map:GetPlatformAtPoint(pt.x, pt.z) then
                    self.inst.Physics:Teleport(pt.x, pt.y, pt.z)
                end
                --缴械攻击目标1秒
                local tcombat = target.components.combat
                if tcombat then
                    local nowcooldown = tcombat:GetCooldown()
                    local newcooldown = nowcooldown + 1 + 8 * FRAMES + 1 -- ?
                    tcombat:OverrideCooldown(newcooldown)
                end
            end
        end
    end
    return oldPushAction(self, bufferedaction, run, try_instant, ...)
end

local oldPreviewAction = LocoMotor.PreviewAction
function LocoMotor:PreviewAction(bufferedaction, run, try_instant, ...)
    if not TheWorld.ismastersim then
        if bufferedaction and bufferedaction.action == ACTIONS.ATTACK then
            local hand = bufferedaction.invobject or
                self.inst.replica.inventory and self.inst.replica.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
            if hand and hand:HasTag("doro_weapon_shadow") and not hand:HasTag("oncooldown") then
                SendModRPCToServer(MOD_RPC["doro"]["doro_attack_movement"], bufferedaction.target)
                return
            end
        end
    end
    return oldPreviewAction(self, bufferedaction, run, try_instant, ...)
end

--doro_ignoreall标签 免疫击退 击飞
--霸体
local controltable = {
    ["knockback"] = true,
    ["mindcontrolled"] = true,
    ["devoured"] = true,
    ["repelled"] = true,
    ["startled"] = true,
    ["snared"] = true,
    ["attacked"] = true,
    ["suspended"] = true,
    ["feetslipped"] = true,
    ["consumehealthcost"] = true,
    ["onfallinvoid"] = true,
    ["toolbroke"] = true,
    ["armorbroke"] = true,
    ["knockedout"] = true,
    yawn = true,
    pinned = true,
    freeze = true,
    wonteatfood = true,
    spooked = true,
    acting = true,
    monkeycursehit = true,
}

local oldStateGraphInstancePushEvent = StateGraphInstance.PushEvent
function StateGraphInstance:PushEvent(eventname, data, ...)
    if controltable[eventname] then
        local inst = self.inst
        if inst
            and inst.doro_ignorecontrol then
            return
        end
    end
    return oldStateGraphInstancePushEvent(self, eventname, data, ...)
end

--饱食度低了无法装备手部物品
local Equippable_replica = require("components/equippable_replica")
local oldreplicaIsRestricted = Equippable_replica.IsRestricted
function Equippable_replica:IsRestricted(target)
    if target and target:HasTag("doro_banhands")
        and self:EquipSlot() == EQUIPSLOTS.HANDS then
        return true
    end
    return oldreplicaIsRestricted(self, target)
end

local Equippable = require("components/equippable")
local oldIsRestricted = Equippable.IsRestricted
function Equippable:IsRestricted(target)
    if target and target:HasTag("doro_banhands")
        and self.equipslot == EQUIPSLOTS.HANDS then
        return true
    end
    return oldIsRestricted(self, target)
end
